using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Drawing; // Added for SystemIcons
using System.IO;
using System.Drawing.Imaging;
using System.Net;
using System.Net.Sockets;

namespace DeviceConfigTool
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            InitializeUI();
        }

        private void InitializeComponent()
        {
            // Set window icon
            // Set window icon directly from file
            string iconPath = @"C:\D_DJ_Disk\2024_worksapce_all\STM32F4-Discovery\ip-scan-and-configure\icon2.ico";
            string pngPath = @"C:\D_DJ_Disk\2024_worksapce_all\STM32F4-Discovery\ip-scan-and-configure\icon.png";
            
            if (System.IO.File.Exists(pngPath)) {
                using (var bmp = new System.Drawing.Bitmap(pngPath)) {
                    this.Icon = System.Drawing.Icon.FromHandle(bmp.GetHicon());
                }
            }
            else if (System.IO.File.Exists(iconPath)) {
                this.Icon = new System.Drawing.Icon(iconPath);
            }
            this.SuspendLayout();// 
            // MainForm
            // 
            this.ClientSize = new System.Drawing.Size(800, 620);
            this.Name = "MainForm";
            this.Text = "IP Scan And Configure Tool";
            this.ResumeLayout(false);

        }

        private UdpScanner _udpScanner;
        private List<DeviceInfo> _devices = new List<DeviceInfo>();
        private List<DeviceInfo> _selectedDevices = new List<DeviceInfo>();
        private ListView _deviceListView;
        private Button _scanButton;
        private Panel _configPanel;
        private TextBox ipTextBox;
        private Button bindButton;

        private void InitializeUI()
        {
            // Scan button
            _scanButton = new Button
            {
                Text = "Scan Devices",
                Location = new System.Drawing.Point(10, 10),
                Size = new System.Drawing.Size(100, 30)
            };
            _scanButton.Click += (s, e) => StartDeviceScan();
            this.Controls.Add(_scanButton);

        // Initialize controls
            ipTextBox = new System.Windows.Forms.TextBox();
            bindButton = new System.Windows.Forms.Button();
            // TextBox configuration
            ipTextBox.Location = new System.Drawing.Point(200, 10);
            ipTextBox.Size = new System.Drawing.Size(100, 20);
            ipTextBox.Text = "192.168.0.100"; // Default IP address
            // Button configuration
            bindButton.Location = new System.Drawing.Point(310, 10);
            bindButton.Size = new System.Drawing.Size(75, 23);
            bindButton.Text = "Bind";
            bindButton.Click += new System.EventHandler(this.BindButton_Click);
            
            // Add controls to the form
            this.Controls.Add(ipTextBox);
            this.Controls.Add(bindButton);

            // Device list view
            _deviceListView = new ListView
            {
                View = View.Details,
                Location = new System.Drawing.Point(10, 50),
                Size = new System.Drawing.Size(780, 380),
                FullRowSelect = true,
                GridLines = true,
                CheckBoxes = true
            };
            _deviceListView.Columns.Add("Select", 55);
            _deviceListView.Columns.Add("IP Address", 90);
            _deviceListView.Columns.Add("MAC Address", 110);
            _deviceListView.Columns.Add("Subnet Mask", 100);
            _deviceListView.Columns.Add("Gateway", 90);
            _deviceListView.Columns.Add("Serial Number", 120);
            _deviceListView.Columns.Add("Software Version", 120);
            _deviceListView.Columns.Add("Cloud Server IP", 110);
            _deviceListView.ItemChecked += DeviceListView_ItemChecked;
            this.Controls.Add(_deviceListView);

            // Configuration panel
            _configPanel = new Panel
            {
                Location = new System.Drawing.Point(10, 440),
                Size = new System.Drawing.Size(780, 150),
                BorderStyle = BorderStyle.FixedSingle
            };
            InitializeConfigPanel();
            this.Controls.Add(_configPanel);

            // Initialize UDP scanner
            _udpScanner = new UdpScanner();
            _udpScanner.DeviceDiscovered += OnDeviceDiscovered;
        }

        private void InitializeConfigPanel()
        {
            _configPanel.Controls.Clear();

            // Scan button (simple text)
            _scanButton = new Button
            {
                Text = "Scan Devices",
                Location = new System.Drawing.Point(10, 10),
                Size = new System.Drawing.Size(100, 30)
            };

            // IP Configuration Group
            var ipGroup = new GroupBox
            {
                Text = "IP Configuration",
                Location = new System.Drawing.Point(10, 10),
                Size = new System.Drawing.Size(300, 130)
            };

            // Declare controls first
            var ipTextBox = new TextBox { Location = new System.Drawing.Point(120, 45), Width = 120 };
            var subnetTextBox = new TextBox { Location = new System.Drawing.Point(120, 70), Width = 120 };
            var gatewayTextBox = new TextBox { Location = new System.Drawing.Point(120, 95), Width = 120 };

            var dhcpCheck = new CheckBox
            {
                Text = "Use DHCP",
                Location = new System.Drawing.Point(10, 20),
                AutoSize = true
            };
            dhcpCheck.CheckedChanged += (s, e) => 
            {
                ipTextBox.Enabled = !dhcpCheck.Checked;
                subnetTextBox.Enabled = !dhcpCheck.Checked;
                gatewayTextBox.Enabled = !dhcpCheck.Checked;
            };

            var ipLabel = new Label { Text = "IP:", Location = new System.Drawing.Point(10, 50) };
            var subnetLabel = new Label { Text = "Subnet:", Location = new System.Drawing.Point(10, 75) };
            var gatewayLabel = new Label { Text = "Gateway:", Location = new System.Drawing.Point(10, 100) };

            ipGroup.Controls.AddRange(new Control[] { dhcpCheck, ipLabel, ipTextBox, subnetLabel, subnetTextBox, gatewayLabel, gatewayTextBox });

            // Device Actions Group
            var actionsGroup = new GroupBox
            {
                Text = "Device Actions",
                Location = new System.Drawing.Point(320, 10),
                Size = new System.Drawing.Size(240, 130)
            };

            var applyBtn = new Button
            {
                Text = "Apply Configuration",
                Location = new System.Drawing.Point(20, 20),
                Width = 200,
                BackColor = System.Drawing.Color.LightGreen
            };
            applyBtn.Click += (s, e) => ApplyConfiguration();

            var restartBtn = new Button 
            { 
                Text = "Restart Device",
                Location = new System.Drawing.Point(20, 50),
                Width = 200
            };
            restartBtn.Click += (s, e) => 
            {
                if (VerifyPassword())
                {
                    if (_selectedDevices.Count == 0)
                    {
                        UpdateStatus("No device selected", false);
                        return;
                    }
                    var packet = new byte[] { 0x06, 0x01, 0x55 };
                    _udpScanner.SendConfiguration(packet, _selectedDevices[0]);
                }
            };

            var factoryResetBtn = new Button 
            { 
                Text = "Factory Reset",
                Location = new System.Drawing.Point(20, 80),
                Width = 200
            };
            factoryResetBtn.Click += (s, e) => 
            {
                if (VerifyPassword())
                {
                    if (_selectedDevices.Count == 0)
                    {
                        UpdateStatus("No device selected", false);
                        return;
                    }
                    var packet = new byte[] { 0x06, 0x01, 0xAA };
                    _udpScanner.SendConfiguration(packet, _selectedDevices[0]);
                }
            };

            var arpCheckBox = new CheckBox
            {
                Text = "Clear ARP Cache",
                Location = new System.Drawing.Point(20, 110),
                Width = 200
            };

            actionsGroup.Controls.AddRange(new Control[] { applyBtn, restartBtn, factoryResetBtn, arpCheckBox });

            // Add PNG to ICO conversion button
            var convertPngBtn = new Button 
            { 
                Text = "Convert PNG to ICO",
                Location = new System.Drawing.Point(10, 50),
                Width = 200
            };
            convertPngBtn.Click += (s, e) => 
            {
                
            };

            // Cloud Settings Group
            var cloudGroup = new GroupBox
            {
                Text = "Cloud Settings",
                Location = new System.Drawing.Point(570, 10),
                Size = new System.Drawing.Size(200, 130)
            };

            var cloudIpLabel = new Label { Text = "Server IP:", Location = new System.Drawing.Point(10, 20), Width = 70 };
            var cloudIpTextBox = new TextBox { Location = new System.Drawing.Point(80, 15), Width = 100 };

            cloudGroup.Controls.AddRange(new Control[] { cloudIpLabel, cloudIpTextBox});

            // Add status bar at bottom of form
            var statusStrip = new StatusStrip();
            var statusLabel = new ToolStripStatusLabel();
            statusStrip.Items.Add(statusLabel);
            statusStrip.Dock = DockStyle.Bottom;

            this.Controls.Add(statusStrip);
            _configPanel.Controls.AddRange(new Control[] { ipGroup, actionsGroup, cloudGroup});
        }

        private void BindButton_Click(object sender, EventArgs e)
        {
            try
            {
                var localIp = IPAddress.Parse(ipTextBox.Text);
                var localEndpoint = new IPEndPoint(localIp, 0); // Port=0 means allocated by system.
                _udpScanner.reBindUdpClient(localEndpoint);
                UpdateStatus("Binding successful.", true);
            }
            catch (FormatException)
            {
                UpdateStatus("Invalid IP address format.", false);
            }
            catch (Exception ex)
            {
                UpdateStatus($"Error: {ex.Message}", false);
            }
        }

        /// <summary>
        /// �� PNG ͼ��ת��Ϊ ICO �ļ�
        /// </summary>
        /// <param name="pngImage">ԭʼ PNG ͼ��</param>
        /// <param name="icoFilePath">Ŀ�� ICO �ļ�·��</param>
        private void ConvertPngToIco(Image pngImage, string icoFilePath)
        {
            // ������ߴ��λͼ��16x16, 32x32, 48x48��
            Bitmap[] iconSizes = new Bitmap[]
            {
                new Bitmap(pngImage, new Size(16, 16)),
                new Bitmap(pngImage, new Size(32, 32)),
                new Bitmap(pngImage, new Size(48, 48))
            };

            // ʹ�� Icon.Save ֱ�ӱ����ߴ�ͼ��
            using (MemoryStream memoryStream = new MemoryStream())
            {
                // ���� Icon ���󣨴ӵ�һ��λͼ��
                using (Icon icon = Icon.FromHandle(iconSizes[2].GetHicon()))
                {
                    // ���浽�ļ�
                    using (FileStream fileStream = new FileStream(icoFilePath, FileMode.Create))
                    {
                        icon.Save(fileStream);
                    }
                }
            }

            // �ͷ���ʱλͼ
            foreach (var bitmap in iconSizes)
            {
                bitmap.Dispose();
            }
        }

        private void DeviceListView_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            var device = _devices[e.Item.Index];
            if (e.Item.Checked)
            {
                if (!_selectedDevices.Contains(device))
                    _selectedDevices.Add(device);
            }
            else
            {
                _selectedDevices.Remove(device);
            }
        }

        private bool VerifyPassword()
        {
            var passwordDialog = new Form()
            {
                Text = "Enter Password",
                Width = 300,
                Height = 180,
                FormBorderStyle = FormBorderStyle.FixedDialog,
                StartPosition = FormStartPosition.CenterParent
            };

            var passwordLabel = new Label { Text = "Password:", Top = 20, Left = 20, Width = 75 };
            var passwordBox = new TextBox { Top = 20, Left = 100, Width = 150, PasswordChar = '*' };
            var errorLabel = new Label { Top = 50, Left = 100, Width = 150, ForeColor = Color.Red, Visible = false };
            var okButton = new Button { Text = "OK", Top = 80, Left = 100, Width = 75 };

            passwordDialog.Controls.Add(passwordLabel);
            passwordDialog.Controls.Add(passwordBox);
            passwordDialog.Controls.Add(errorLabel);
            passwordDialog.Controls.Add(okButton);

            bool result = false;
            
            okButton.Click += (s, e) => 
            {
                if (passwordBox.Text == "123456")
                {
                    result = true;
                    passwordDialog.Close();
                }
                else
                {
                    errorLabel.Text = "Incorrect password!";
                    errorLabel.Visible = true;
                }
            };

            passwordBox.KeyDown += (s, e) => 
            {
                if (e.KeyCode == Keys.Enter)
                {
                    if (passwordBox.Text == "123456")
                    {
                        result = true;
                        passwordDialog.Close();
                    }
                    else
                    {
                        errorLabel.Text = "Incorrect password!";
                        errorLabel.Visible = true;
                    }
                }
            };

            passwordDialog.ShowDialog();
            return result;
        }

        private void ApplyConfiguration()
        {
            if (_selectedDevices.Count == 0)
            {
                UpdateStatus("No devices selected", false);
                return;
            }

            // Check if any critical operation is requested
            // var actionsGroup = _configPanel.Controls.OfType<GroupBox>().First(g => g.Text == "Device Actions");
            // var restartBtn = actionsGroup.Controls.OfType<Button>().First(b => b.Text == "Restart");
            // var factoryResetBtn = actionsGroup.Controls.OfType<Button>().First(b => b.Text == "Factory Reset");

            // if ((restartBtn.Enabled || factoryResetBtn.Enabled) && !VerifyPassword())
            // {
            //     UpdateStatus("Password verification failed", false);
            //     return;
            // }

            try
            {
                UpdateStatus($"Applying configuration to {_selectedDevices.Count} devices...", true);

                // Get UI controls with unique variable names
                var ipConfigGroup = _configPanel.Controls.OfType<GroupBox>().First(g => g.Text == "IP Configuration");
                var dhcpCheckBox = ipConfigGroup.Controls.OfType<CheckBox>().First();
                var ipAddressBox = ipConfigGroup.Controls.OfType<TextBox>().First(t => t.Location.Y == 45);
                var subnetMaskBox = ipConfigGroup.Controls.OfType<TextBox>().First(t => t.Location.Y == 70);
                var gatewayBox = ipConfigGroup.Controls.OfType<TextBox>().First(t => t.Location.Y == 95);

                var deviceActionsGroup = _configPanel.Controls.OfType<GroupBox>().First(g => g.Text == "Device Actions");
                var arpCheckBox = deviceActionsGroup.Controls.OfType<CheckBox>().First();
                // var restartButton = deviceActionsGroup.Controls.OfType<Button>().First(b => b.Text == "Restart");
                // var resetButton = deviceActionsGroup.Controls.OfType<Button>().First(b => b.Text == "Factory Reset");

                var cloudSettingsGroup = _configPanel.Controls.OfType<GroupBox>().First(g => g.Text == "Cloud Settings");
                var cloudIpBox = cloudSettingsGroup.Controls.OfType<TextBox>().First();

                // Create device info with current settings
                var deviceInfo = new DeviceInfo
                {
                    UseDhcp = dhcpCheckBox.Checked,
                    IpAddress = ipAddressBox.Text,
                    SubnetMask = subnetMaskBox.Text,
                    Gateway = gatewayBox.Text,
                    ClearArp = arpCheckBox.Checked
                };

                // Create config packet
                var configData = deviceInfo.ToByteArray(
                    restart: false,
                    factoryReset: false,
                    clearArp: arpCheckBox.Checked,
                    cloudServerIp: cloudIpBox.Text
                );

                // Register for config status updates
                _udpScanner.ConfigStatusReceived += (success, message) => 
                    UpdateStatus(message, success);

                // Send configuration to all selected devices
                foreach (var device in _selectedDevices)
                {
                    device.MacAddress = _deviceListView.Items
                        .Cast<ListViewItem>()
                        .First(i => i.SubItems[2].Text == device.MacAddress)
                        .SubItems[2].Text;
                    
                    _udpScanner.SendConfiguration(configData, device);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"Error: {ex.Message}", false);
            }
        }

        private void UpdateStatus(string message, bool isSuccess)
        {
            if (InvokeRequired)
            {
                Invoke(new Action(() => UpdateStatus(message, isSuccess)));
                return;
            }

            var statusStrip = this.Controls.OfType<StatusStrip>().First();
            var statusLabel = statusStrip.Items.OfType<ToolStripStatusLabel>().First();
            statusLabel.Text = message;
            statusLabel.ForeColor = isSuccess ? System.Drawing.Color.Green : System.Drawing.Color.Red;
        }

        private void StartDeviceScan()
        {
            _devices.Clear();
            _deviceListView.Items.Clear();
            _selectedDevices.Clear();
            _scanButton.Enabled = false;
            _scanButton.Text = "Scanning...";
            _udpScanner.StartScanning();
            
            // Stop scanning after 2 seconds
            var timer = new Timer { Interval = 2000 };
            timer.Tick += (s, e) => {
                timer.Stop();
                _udpScanner.StopScanning();
                _scanButton.Enabled = true;
                _scanButton.Text = "Scan Devices";
            };
            timer.Start();
        }

        private void OnDeviceDiscovered(DeviceInfo device)
        {
            if (device == null) return;

            if (InvokeRequired)
            {
                Invoke(new Action<DeviceInfo>(OnDeviceDiscovered), device);
                return;
            }

            try
            {
                if (!string.IsNullOrEmpty(device.IpAddress) && 
                    !string.IsNullOrEmpty(device.MacAddress))
                {
                    _devices.Add(device);
                    var item = new ListViewItem(new[] {
                        "",
                        device.IpAddress ?? "",
                        device.MacAddress ?? "",
                        device.SubnetMask ?? "",
                        device.Gateway ?? "",
                        device.SerialNumber ?? "",
                        device.SoftwareVersion ?? "",
                        device.CloudServerIp ?? ""
                    });
                    item.Checked = true;
                    _deviceListView.Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                UpdateStatus($"Error adding device: {ex.Message}", false);
            }
        }
    }
}
